<?php

namespace App\Http\Logic\Api;

use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

class WechatAuth
{
    protected Client $client;

    protected mixed $appid;

    protected mixed $secret;

    public function __construct()
    {

        $this->client = new Client([
            'base_uri' => 'https://api.weixin.qq.com',
            'verify' => false,
        ]);
        $this->appid = env('WECHAT_APPID');
        $this->secret = env('WECHAT_SECRET');
    }

    /**
     * @throws GuzzleException
     * @throws Exception
     */
    public function getUserPhone(string $code)
    {
        try {
            $url = '/wxa/business/getuserphonenumber?access_token=' . $this->getAccessToken();
            Log::info('[wechatGetUserPhone]请求接口：' . $url);
            $responses = $this->client->post($url, [
                'json' => [
                    'code' => $code
                ]
            ])->getBody()->getContents();
            Log::info('[wechatGetUserPhone]接口返回值：' . $responses);
            $data = json_decode($responses, true);
            if (!empty($data['errcode'])) {
                throw new Exception($data['errmsg']);
            }

            return $data['phone_info'] ?? '';
        } catch (Exception $e) {
            Log::info('[wechatGetUserPhone]error 接口异常：' . $e->getMessage());

            throw new Exception($e->getMessage());
        }
    }

    /**
     * @throws GuzzleException
     * @throws Exception
     */
    public function login(string $code)
    {
        try {
            $url = '/sns/jscode2session?appid=' . $this->appid . '&secret=' . $this->secret . '&js_code=' . $code . '&grant_type=authorization_code';
            Log::info('[wechatLogin]请求接口：' . $url);
            $responses = $this->client->get($url)->getBody()->getContents();
            Log::info('[wechatLogin]接口返回值：' . $responses);
            $data = json_decode($responses, true);
            if (!empty($data['errcode'])) {
                throw new Exception($data['errmsg']);
            }

            return $data;
        } catch (Exception $e) {
            Log::info('[wechatLogin]error 接口异常：' . $e->getMessage());

            throw new Exception($e->getMessage());
        }
    }

    /**
     * @throws GuzzleException
     * @throws Exception
     */
    public function getAccessToken()
    {
        try {
            //如果缓存中存在那么直接取
            $accessToken = Cache::get('wechat_access_token');
            if (!empty($accessToken)) {
                Log::info('[wechatGetAccessToken]获取缓存accessToken：' . $accessToken);

                return $accessToken;
            }

            //不存在调用微信获取，并放入缓存，存放2小时
            $url = '/cgi-bin/token?grant_type=client_credential&appid=' . $this->appid . '&secret=' . $this->secret;
            Log::info('[wechatGetAccessToken]请求接口：' . $url);
            $responses = $this->client->get($url)->getBody()->getContents();
            Log::info('[wechatGetAccessToken]接口返回值：' . $responses);
            $data = json_decode($responses, true);
            if (empty($data['access_token'])) {
                throw new Exception($data['errmsg']);
            }

            Cache::put('wechat_access_token', $data['access_token'], $data['expires_in'] ?? 7200);

            return $data['access_token'];
        } catch (Exception $e) {
            Log::info('[wechatGetAccessToken]error 接口异常：' . $e->getMessage());

            throw new Exception($e->getMessage());
        }
    }
}
